<template>
  <div class="container" ref="container">
    <div class="box"></div>
  </div>
</template>
<script setup lang="ts">
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls'
// 引入性能监视器
import Stats from 'three/examples/jsm/libs/stats.module.js'
// 导入动画库
import gsap from 'gsap'
// 导入dat.gui
import * as dat from 'dat.gui'

import { onMounted, ref } from 'vue'
import earth from '@/assets/earth.jpg'
import cizhuan from '@/assets/瓷砖.jpg'
import wheel from '@/assets/转弯.png'
const container: any = ref(null)
// 创建性能监视器
const stats = new (<any>Stats)()

// 创建场景
const scene = new THREE.Scene()
scene.background = new THREE.Color('rgb(0,47,167)')

// 创建相机
const camera = new THREE.PerspectiveCamera(
  100,
  window.innerWidth / (window.innerHeight - 1),
  0.1,
  2000
)
// 默认情况下，当我们调用scene.add()的时候，物体将会被添加到(0,0,0)坐标。
// 但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生，我们只需要将摄像机稍微向外移动一些即可。
camera.position.set(0, 10, 100)

// // 坐标网格
// const gridHelper = new THREE.GridHelper(
//   1000,
//   100,
//   new THREE.Color('#F7F7F7'),
//   new THREE.Color('#F7F7F7')
// )
// scene.add(gridHelper)

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
  precision: 'highp', //着色器精度
  antialias: true //抗锯齿
})
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight - 1)

// 轨道控制器
const orbitControls = new OrbitControls(camera, renderer.domElement)
orbitControls.update()

function animate() {
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
  stats.update()
  orbitControls.update()
}

// 画面尺寸变化
window.addEventListener('resize', () => {
  console.log('尺寸变化')
  // 摄像机视锥体的长宽比，通常是使用画布的宽/画布的高。默认值是1（正方形画布）。
  camera.aspect = window.innerWidth / (window.innerHeight - 1)
  camera.updateProjectionMatrix()
  //渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight - 1)
  renderer.setPixelRatio(window.devicePixelRatio)
})

// 创建一个立方体
const geometry = new THREE.BoxGeometry(20, 10, 10)
const material = new THREE.MeshBasicMaterial({
  // color: 0xff00ff, //使用纹理贴图的时候不要设置颜色，否则样式会混合
  side: THREE.DoubleSide
})
const box = new THREE.Mesh(geometry, material)

// 创建一个球
const sphereGeometry = new THREE.SphereGeometry(10)
const sphere = new THREE.Mesh(sphereGeometry, material)
sphere.translateY(20)

// 创建一个圆
const circleGeometry = new THREE.CircleGeometry(5, 32)
const circle = new THREE.Mesh(circleGeometry, material)
circle.translateY(50)
// 创建一个组
const group = new THREE.Group()
group.add(box, sphere, circle) //将box添加到父对象中
scene.add(group)

// 创建辅助坐标
const axesHelper = new THREE.AxesHelper(20)
scene.add(axesHelper)

// 创建纹理贴图
const texture = new THREE.TextureLoader().load(earth)
material.map = texture

// 纹理对象阵列(创建一个地板)
const planeGeometry = new THREE.PlaneGeometry(2000, 2000)
const textureCizhuan = new THREE.TextureLoader().load(cizhuan)
const meshBasicMaterial = new THREE.MeshBasicMaterial({
  map: textureCizhuan
})
textureCizhuan.wrapS = THREE.RepeatWrapping
textureCizhuan.wrapT = THREE.RepeatWrapping
textureCizhuan.repeat.set(20, 20)
const plane = new THREE.Mesh(planeGeometry, meshBasicMaterial)
plane.rotateX(-Math.PI / 2)
group.add(plane)

// 矩形平面网格模型设置背景透明的png贴图
const PlaneGeometry = new THREE.PlaneGeometry(60, 60) //默认在XOY平面上
const textureLoader = new THREE.TextureLoader()
const MeshBasicMaterial = new THREE.MeshBasicMaterial({
  map: textureLoader.load(wheel),
  transparent: true, //使用背景透明的png贴图，注意开启透明计算
  side: THREE.DoubleSide
})
const PlaneMesh = new THREE.Mesh(PlaneGeometry, MeshBasicMaterial)
PlaneGeometry.rotateX(-Math.PI / 4)
PlaneMesh.translateY(80)
group.add(PlaneMesh)

// 页面挂载后渲染
onMounted(() => {
  console.log(container.value)
  container.value?.appendChild(renderer.domElement)
  container.value?.appendChild(stats.domElement) //性能监视器
  animate()
})
</script>
<style scoped>
.box {
  width: 100px;
  height: 100px;
  position: absolute;
}
</style>
